package com.cskaoyan.user.controller;

import com.alibaba.fastjson.JSON;
import com.cskaoyan.mall.commons.exception.ValidateException;
import com.cskaoyan.mall.commons.result.ResponseData;
import com.cskaoyan.mall.commons.result.ResponseUtil;
import com.cskaoyan.mall.commons.util.CookieUtil;
import com.cskaoyan.mall.commons.util.jwt.JwtTokenUtils;
import com.cskaoyan.user.constants.UserRetCode;
import com.cskaoyan.user.dal.entitys.MemberInfo;
import com.cskaoyan.user.dto.UserLoginResponse;
import com.cskaoyan.user.form.KaptchaCodeRequest;
import com.cskaoyan.user.form.UserLoginRequest;
import com.cskaoyan.user.service.IKaptchaService;
import com.cskaoyan.user.service.ILoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @Description：
 * @Author： 黄武
 * @Date： 2022/12/3 18:05
 */
@RestController
@RequestMapping("/user")
public class LoginController {
    @Autowired
    IKaptchaService kaptchaService;

    @Autowired
    ILoginService loginService;

    /**
     * 登陆
     *
     * @param userLoginRequest
     * @param request
     * @return
     */
    @PostMapping("/login")
    public ResponseData login(@RequestBody UserLoginRequest userLoginRequest,
                              HttpServletRequest request, HttpServletResponse response) {
        // 验证码
        String captcha = userLoginRequest.getCaptcha();

        // 验证验证码
        KaptchaCodeRequest codeRequest = new KaptchaCodeRequest();
        String uuid = CookieUtil.getCookieValue(request, "kaptcha_uuid");
        codeRequest.setUuid(uuid);
        codeRequest.setCode(captcha);
        kaptchaService.validateKaptchaCode(codeRequest);

        // 验证用户信息
        UserLoginResponse login = loginService.login(userLoginRequest);
        // 如果一切正常，那么生成数字签名JWT
        MemberInfo info = new MemberInfo(login.getId(), login.getUsername());
        String jsonString = JSON.toJSONString(info);
        String token = JwtTokenUtils.builder().msg(jsonString).build().creatJwtToken();
        Cookie access_token = new Cookie("access_token", token);
        access_token.setPath("/");
        CookieUtil.setCookie(response, access_token);
        login.setToken(token);
        return new ResponseUtil<>().setData(login);
    }


    /**
     * 验证是否已登陆
     *
     * @return
     */
    @GetMapping("/login")
    public ResponseData loginValidate(HttpServletRequest request) {
        // 获取放在请求头里的用户信息
        String userInfo = request.getHeader("user_info");
        MemberInfo info = JSON.parseObject(userInfo, MemberInfo.class);
        // 判空
        if (info == null) {
            throw new ValidateException(UserRetCode.TOKEN_VALID_FAILED.getCode(),
                    UserRetCode.TOKEN_VALID_FAILED.getMessage());
        }
        // todo 这里我也不确定是否需要到数据库中去对比是否存在该用户，先对比一下以防意外
        loginService.verifyLogin(info);
        // 如果查找没报错，说明存在当前用户，且验证了请求头，表示已登陆
        return new ResponseUtil<>().setData(info);
    }


    /**
     * 实现退出登陆功能
     *
     * @param request
     * @return
     */
    @GetMapping("/loginOut")
    public ResponseData loginOut(HttpServletRequest request, HttpServletResponse response) {
        // 获取放在请求头里的用户信息
        String userInfo = request.getHeader("user_info");
        MemberInfo info = JSON.parseObject(userInfo, MemberInfo.class);
        // 判空
        if (info == null) {
            throw new ValidateException(UserRetCode.TOKEN_VALID_FAILED.getCode(),
                    UserRetCode.TOKEN_VALID_FAILED.getMessage());
        }
        if (info.getUid() < 0 || StringUtils.isEmpty(info.getUsername())) {
            throw new ValidateException(UserRetCode.USER_INFOR_INVALID.getCode(),
                    UserRetCode.USER_INFOR_INVALID.getMessage());
        }
        // 有参数，且不为空，那么就表示已登陆
        // 实现退出登陆功能，需要清除现有的cookie
        Cookie cookie = new Cookie("access_token", null);
        cookie.setMaxAge(0);
        cookie.setPath("/");
        CookieUtil.setCookie(response, cookie);
        return new ResponseUtil<>().setData(null);
    }
}
